package com.sjdq.imp

import com.sqi.reactive.BASE_MODULE
import com.sqi.reactive.TableInfo
import com.sqi.reactive.WEB_BASE_DIR
import com.sqi.reactive.WEB_VIEWS_BASE_DIR
import java.io.File

/**
 *
 *
 * @author: zhangfx
 *
 * @create: 2020-06-12 15:40
 **/
fun TableInfo.createView() {
    val indexViewDir = File(WEB_VIEWS_BASE_DIR, "${packageName}/${this.entityName?.toLowerCase()}")
    val indexViewFile = File(indexViewDir, "index.vue")
    if (indexViewFile.exists()) {
        throw RuntimeException("""${packageName}/${this.entityName?.toLowerCase()} 资源已经存在，放弃生成""")
    } else {
        this.createViewIndex()
        this.createViewDetail()
        this.createViewEdit()
        this.createViewApi()
        this.createViewRouterJS()
        this.createViewLang()
    }
}

fun TableInfo.createViewIndex() {
    val code = """
<template>
  <div class="app-container">
    <el-card>
      <el-form :inline="true" style="margin-bottom: -22px;">
        ${this.columnInfoList?.filter { !it.isPrimaryKey() }?.joinToString("\n        ") {
        """
        <el-form-item :label="${'$'}t('${this.packageName}.${this.entityName?.toLowerCase()}.query.${it.fieldName}')">
          <el-input v-model="params.eq_${it.fieldName}" />
        </el-form-item>
        """.trim()
    }}
        <el-form-item>
          <el-button type="primary" @click="query">{{ ${'$'}t('comm.btn.searchBtn') }}</el-button>
          <el-button type="default" @click="reset">{{ ${'$'}t('comm.btn.resetBtn') }}</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card style="margin-top:20px;">
      <div slot="header" style="display: flex; justify-content: space-between; align-items: center;">
        <span>{{ ${'$'}t('${this.packageName}.${this.entityName?.toLowerCase()}.table.tableTitle') }}</span>
        <el-button type="primary" icon="el-icon-circle-plus-outline" @click="toCreate">
          {{ ${'$'}t('${this.packageName}.${this.entityName?.toLowerCase()}.table.create') }}
        </el-button>
      </div>
      <data-list
        ref="dataList"
        pageable
        :load-func="entityApi.page"
        :parameter="params"
        :delete-func="entityApi.delete"
      >
        <template slot="row">
          <el-table-column type="index" align="center" width="50" />
          ${this.columnInfoList?.filter { !it.isPrimaryKey() }?.joinToString("\n          ") {
        """
          <el-table-column prop="${it.fieldName}" :label="${'$'}t('${this.packageName}.${this.entityName?.toLowerCase()}.columns.${it.fieldName}')" align="center" />
          """.trim()
    }}
          <el-table-column :label="${'$'}t('comm.table.columns.operation')" align="center" width="150">
            <template slot-scope="scope">
              <router-link :to="{ name: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}Detail', params: { id: scope.row.id }}">
                <el-button size="mini" type="text" style="padding:7px;">
                  {{ ${'$'}t('comm.table.columns.operation_detail') }}
                </el-button>
              </router-link>
              <el-button size="mini" type="text" style="padding:7px;" @click="${'$'}refs.dataList.toEdit(scope.row)">
                {{ ${'$'}t('comm.table.columns.operation_edit') }}
              </el-button>
              <el-button size="mini" type="text" style="padding:7px;" @click="${'$'}refs.dataList.toDelete(scope.row, `确认删除订单【${'$'}{scope.row.id}】?`)">
                {{ ${'$'}t('comm.table.columns.operation_delete') }}
              </el-button>
            </template>
          </el-table-column>
        </template>
        <template slot="edit-form" slot-scope="scope">
          <edit :id="scope.editDataId" :is-edit="scope.isEdit" @afterSave="${'$'}refs.dataList.afterSave" @afterCancel="${'$'}refs.dataList.afterCancel" />
        </template>
      </data-list>
    </el-card>
  </div>
</template>

<script>

import entityApi from '@/api/${this.packageName}/${this.entityName?.toLowerCase()}'
import Edit from './components/Edit'
import DataList from '@/views/components/DataList'

const defaultParams = {
  page: 1,
  size: 10,
  ${this.columnInfoList?.joinToString(",\n  ") {
        """
  eq_${it.fieldName}: null
  """.trim()
    }}
}
export default {
  name: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}',
  components: {
    Edit,
    DataList
  },
  data() {
    return {
      entityApi: entityApi,
      params: Object.assign({}, defaultParams)
    }
  },
  computed: {
  },
  mounted: function() {
  },
  methods: {
    reset() {
      this.params = Object.assign({}, defaultParams)
    },
    query() {
      this.${'$'}refs.dataList.query()
    },
    toCreate() {
      this.${'$'}refs.dataList.toCreate()
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>

</style>

""".trim()
    val indexViewDir = File(WEB_VIEWS_BASE_DIR, "${packageName}/${this.entityName?.toLowerCase()}")
    if (!indexViewDir.exists()) {
        indexViewDir.mkdirs()
    }
    val indexViewFile = File(indexViewDir, "index.vue")
    indexViewFile.writeText(code)
}


fun TableInfo.createViewDetail() {
    val code = """
<template>
  <div class="app-container detail-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>${this.entityName}详情</span>
      </div>
      <div class="detail">
        <el-row :gutter="10">
          ${this.columnInfoList?.filter { !it.isPrimaryKey() }?.joinToString("\n          ") {
        """
          <el-col :span="12">
            <div class="detail_label">{{ ${'$'}t('${this.packageName}.${this.entityName?.toLowerCase()}.columns.${it.fieldName}') }}:</div>
            <div class="detail_value">{{ detail.${it.fieldName} }}</div>
          </el-col>
          """.trim()
    }}
        </el-row>
      </div>
    </el-card>
  </div>
</template>

<script>
import entityApi from '@/api/${this.packageName}/${this.entityName?.toLowerCase()}'

export default {
  name: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}Detail',
  components: {
  },
  data() {
    return {
      id: +this.${'$'}route.params.id,
      detail: {}
    }
  },
  mounted: function() {
    this.loadData()
  },
  methods: {
    loadData() {
      entityApi.get(this.id).then(resp => {
        this.detail = resp.data
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>

</style>
""".trim()
    val indexViewDir = File(WEB_VIEWS_BASE_DIR, "${packageName}/${this.entityName?.toLowerCase()}")
    if (!indexViewDir.exists()) {
        indexViewDir.mkdirs()
    }
    val indexViewFile = File(indexViewDir, "detail.vue")
    indexViewFile.writeText(code)
}


fun TableInfo.createViewEdit() {
    val code = """
<template>
  <el-form ref="form" v-loading="loading" :model="formData" :rules="rules" label-width="100px">
    ${this.columnInfoList?.filter { !it.isPrimaryKey() && !it.fieldName.equals("createTime") }?.joinToString("\n    ") {
        """
    <el-form-item :label="${'$'}t('${this.packageName}.${this.entityName?.toLowerCase()}.columns.${it.fieldName}')" prop="${it.fieldName}">
      <el-input v-model="formData.${it.fieldName}" />
    </el-form-item>
    """.trim()
    }}
    <el-form-item>
      <el-button type="primary" :loading="isSaving" @click="onSave">{{ ${'$'}t('comm.btn.saveBtn') }}</el-button>
      <el-button @click="onCancel">{{ ${'$'}t('comm.btn.cancelBtn') }}</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
import { mapGetters } from 'vuex'
import entityApi from '@/api/${this.packageName}/${this.entityName?.toLowerCase()}'

/**
  event: afterSave, afterCancel
*/
export default {
  components: {
  },
  props: {
    isEdit: { type: Boolean, default: false },
    id: { type: Number, default: null }
  },
  data() {
    const defaultFromData = {
      ${this.columnInfoList?.joinToString(",\n      ") {
        """
      ${it.fieldName}: null
      """.trim()
    }}
    }
    return {
      loading: false,
      isSaving: false,
      formData: defaultFromData,
      rules: { // trigger: change|blur
        field1: [
          { required: true, message: '请输入系统编码', trigger: 'change' },
          { min: 2, max: 30, message: '长度在 2 到 30 个字符', trigger: 'change' }
        ],
        field2: [
          { required: true, message: '请输入系统名称', trigger: 'change' },
          { min: 2, max: 30, message: '长度在 2 到 30 个字符', trigger: 'change' }
        ]
      }
    }
  },
  computed: {
    ...mapGetters([
      'user'
    ])
  },
  mounted: function() {
    if (this.isEdit) {
      //
      this.loadData()
    } else {
      //
    }
  },
  methods: {
    loadData() {
      this.loading = true
      entityApi.get(this.id).then(resp => {
        this.loading = false
        if (resp.code === 0) {
          this.formData = resp.data
        } else {
          this.${'$'}message({ message: resp.message, type: 'warning' })
        }
      }).catch(() => {
        this.loading = false
      })
    },
    onSave() {
      this.isSaving = true
      this.${'$'}refs.form.validate((valid) => {
        if (valid) {
          this.save()
        } else {
          this.isSaving = false
          return false
        }
      })
    },
    save() {
      let method = this.isEdit ? 'update' : 'insert'
      entityApi[method](this.formData).then((resp) => {
        this.isSaving = false
        if (resp.code === 0) {
          this.${'$'}message({ message: '保存成功', type: 'success' })
          this.${'$'}emit('afterSave')
        } else {
          this.${'$'}message({ message: resp.message, type: 'warning' })
        }
      }).catch(() => {
        this.isSaving = false
      })
    },
    onCancel() {
      this.${'$'}emit('afterCancel')
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>

</style>

""".trim()
    val indexViewDir = File(WEB_VIEWS_BASE_DIR, "${packageName}/${this.entityName?.toLowerCase()}/components")
    if (!indexViewDir.exists()) {
        indexViewDir.mkdirs()
    }
    val indexViewFile = File(indexViewDir, "Edit.vue")
    indexViewFile.writeText(code)
}


fun TableInfo.createViewApi() {
    val code = """
import request from '@/utils/request'

const basePath = '/${this.packageName}/${this.entityName?.decapitalize()}'

export default {
  /**
   * 分页查询
   */
  page: (params) => request.get(`${'$'}{basePath}/query_page`, { params }).then(resp => resp.data),
  /**
   * 列表查询
   */
  list: (params) => request.get(`${'$'}{basePath}/query_list`, { params }).then(resp => resp.data),
  /**
   * 根据ID查询
   */
  get: (id) => request.get(`${'$'}{basePath}/get/${'$'}{id}`).then(resp => resp.data),
  /**
   * 保存
   * @param data
   */
  insert: (data) => request.post(`${'$'}{basePath}/save`, data).then(resp => resp.data),
  /**
   * 修改
   * @param data
   */
  update: (data) => request.post(`${'$'}{basePath}/update/${'$'}{data.id}`, data).then(resp => resp.data),
  /**
   * 删除
   * @param id
   */
  delete: (id) => request.post(`${'$'}{basePath}/delete/${'$'}{id}`, { id }).then(resp => resp.data)
}

""".trim()
    val indexViewDir = File(WEB_BASE_DIR, "api/${packageName}")
    if (!indexViewDir.exists()) {
        indexViewDir.mkdirs()
    }
    val indexViewFile = File(indexViewDir, "${this.entityName?.toLowerCase()}.js")
    indexViewFile.writeText(code)
}


fun TableInfo.createViewRouterJS() {
    val entityRouteCode = """
    {
      path: '${this.entityName?.decapitalize()}',
      component: () => import('@/views/$BASE_MODULE/${this.packageName}/${this.entityName?.toLowerCase()}'),
      name: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}',
      meta: { title: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}', icon: 'chart', noCache: false }
    },
    {
      path: '${this.entityName?.decapitalize()}-detail',
      component: () => import('@/views/$BASE_MODULE/${this.packageName}/${this.entityName?.toLowerCase()}/detail'),
      name: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}Detail',
      hidden: true,
      meta: { title: '${this.packageName?.capitalize()}${this.entityName?.capitalize()}Detail', icon: 'chart', noCache: false }
    }// ##APPEND_REPLACE##
    
""".trim()

    val code = """
/** When your routing table is too long, you can split it into small modules**/

import Layout from '@/layout'

const router = {
  path: '/${this.packageName}',
  component: Layout,
  redirect: 'noRedirect',
  alwaysShow: true,
  name: '${this.packageName}',
  meta: {
    title: '${this.packageName?.capitalize()}',
    icon: 'chart'
  },
  children: [
    $entityRouteCode
  ]
}
export default router
""".trim()

    val importCode = """
import ${this.packageName}Router from './modules/${this.packageName}'
// ##APPEND_IMPORT_REPLACE##
""".trimIndent()

    val exportRouteCode = """
${this.packageName}Router// ##APPEND_ROUTER_REPLACE##
""".trimIndent()

    val routerJsDir = File(WEB_BASE_DIR, "router")
    val modulesDirFile = File(routerJsDir, "modules")
    if (!modulesDirFile.exists()) {
        modulesDirFile.mkdirs()
    }
    val routerJsFile = File(routerJsDir, "modules/${this.packageName}.js")
    val erpRouterJsFile = File(routerJsDir, "$BASE_MODULE.js")
    if (!routerJsFile.exists()) {
        routerJsFile.writeText(code)
        var content = erpRouterJsFile.readText()
        content = content.replace("// ##APPEND_IMPORT_REPLACE##", importCode)
        content = content.replace("// ##APPEND_ROUTER_REPLACE##", ",\n  $exportRouteCode")
        erpRouterJsFile.writeText(content)
    } else {
        var content = routerJsFile.readText()
        content = content.replace("// ##APPEND_REPLACE##", ",\n    $entityRouteCode")
        routerJsFile.writeText(content)
    }
}


fun TableInfo.createViewLang() {
    val routeCode = """
${this.packageName?.capitalize()}${this.entityName?.capitalize()}: '${this.tableComment}'// ##APPEND_ROUTE_REPLACE##
""".trimIndent()

    val entityCode = """
  ${this.entityName?.toLowerCase()}: {
    query: {
      ${this.columnInfoList?.joinToString(",\n      ") { """${it.fieldName}: '${it.columnComment}'""" }}
    },
    btn: {
    },
    table: {
      tableTitle: '${this.entityName?.capitalize()}列表',
      create: '新增${this.entityName?.capitalize()}'
    },
    columns: {
      ${this.columnInfoList?.joinToString(",\n      ") { """${it.fieldName}: '${it.columnComment}'""" }}
    }
  }// ##APPEND_ENTITY_REPLACE##
""".trim()

    val code = """
export default {
  route: {
    ${this.packageName?.capitalize()}: '${this.packageComment}',
    $routeCode
  },
  $entityCode
}
""".trim()
    val entityLangDir = File(WEB_BASE_DIR, "lang/modules/${packageName}")
    if (!entityLangDir.exists()) {
        entityLangDir.mkdirs()
    }
    val zhLangFile = File(entityLangDir, "zh.js")
    if (!zhLangFile.exists()) {
        zhLangFile.writeText(code)

        val allZhLangFile = File(File(WEB_BASE_DIR, "lang"), "zh.js")
        var content = allZhLangFile.readText()
        content = content.replace("// ##APPEND_IMPORT_REPLACE##", """import ${this.packageName}ZhLocale from './modules/${this.packageName}/zh'${'\n'}// ##APPEND_IMPORT_REPLACE##""".trimIndent())
        content = content.replace("// ##APPEND_ENTITY_REPLACE##", """${this.packageName}: ${this.packageName}ZhLocale,${'\n'}  // ##APPEND_ENTITY_REPLACE##""")
        content = content.replace("// ##APPEND_ROUTE_REPLACE##", """...${this.packageName}ZhLocale.route,${'\n'}    // ##APPEND_ROUTE_REPLACE##""")
        allZhLangFile.writeText(content)
    } else {
        var content = zhLangFile.readText()
        content = content.replace("// ##APPEND_ROUTE_REPLACE##", ",\n    $routeCode")
        content = content.replace("// ##APPEND_ENTITY_REPLACE##", ",\n  $entityCode")
        zhLangFile.writeText(content)
    }

}